package util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt 工具类
 *
 * @author 李南广
 */
public class JwtUtil {
    /**
     * 创建token
     *
     * @param claims  存放在token中的信息
     * @param secret  秘钥
     * @param outTime 过期时间单位秒
     */
    public static String create(Map<String, String> claims, String secret, long outTime) {
        try {
            Date expirationTime = new Date(System.currentTimeMillis() + outTime * 1000);
            Algorithm algorithm = Algorithm.HMAC256(secret);
            Map<String, Object> headerMap = new HashMap<>(2);
            headerMap.put("type", "JWT");
            headerMap.put("alg", "HS256");
            JWTCreator.Builder builder = JWT.create().withHeader(headerMap);
            for (String key : claims.keySet()) {
                builder.withClaim(key, claims.get(key));
            }
            return builder.withExpiresAt(expirationTime).sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 校验jwt 合法性 返回claims
     *
     * @param token 秘钥
     * @throws JWTDecodeException       token 解码失败
     * @throws IllegalArgumentException token格式不正确不是 aaa.bbb.ccc
     * @throws TokenExpiredException    token超时
     */
    public static Map<String, Claim> verifyToken(String token, String tokenSecret) throws JWTDecodeException, IllegalArgumentException, TokenExpiredException {
        DecodedJWT decodedJWT;
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(tokenSecret)).build();
        decodedJWT = verifier.verify(token);
        return decodedJWT.getClaims();
    }

    public static void main(String[] args) {
        Map<String, String> maps = new HashMap<>(2);
        maps.put("uid", "1");
        maps.put("roles", "admin|guest");
        String token = JwtUtil.create(maps, "ninth-sky", 10);
        System.out.println(token);
        try {
            Map<String, Claim> claims = verifyToken(token, "ninth-sky");
            for (Map.Entry<String, Claim> entry : claims.entrySet()) {
                System.out.println(entry.getKey() + " : " + entry.getValue().asString());
            }
        } catch (JWTDecodeException | IllegalArgumentException e) {
            e.printStackTrace();
            System.out.println("token非法（格式）");
        } catch (TokenExpiredException ignored) {
            System.out.println("token已过期");
        }
    }

}
